package com.hyw.cm.server;

import java.util.Objects;
import java.util.ServiceLoader;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.hyw.cm.common.protocal.spi.IMessage;
import com.hyw.cm.common.protocal.spi.IProtocalDriver;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;

final class ProtocolEncoderRouter extends MessageToByteEncoder<IMessage> {

  private static final Logger log = LoggerFactory.getLogger(ProtocolEncoderRouter.class);

  @Override
  protected void encode(ChannelHandlerContext ctx, IMessage msg, ByteBuf out) throws Exception {
    IProtocalDriver driver = null;

    // find the target encoder
    ServiceLoader<IProtocalDriver> drivers = ServiceLoader.load(IProtocalDriver.class);
    for (IProtocalDriver dr : drivers) {
      if (Objects.nonNull(dr.getEncoder()) && dr.getEncoder().isSupport(msg)) {
        driver = dr;
        break;
      }
    } // end of encoder selection

    if (Objects.nonNull(drivers)) {
      // add expected decoder into pineline
      ctx.pipeline().replace(this, driver.getEncoder().getName(), (ChannelHandler) driver.getEncoder().create());
      log.info("add encoder for {} ", driver.getEncoder().getName());
    } else {
      log.warn("No Encoder for msg:{}", msg);
    }
  }

}
